﻿using CommunityToolkit.Mvvm.ComponentModel;
using CommunityToolkit.Mvvm.Input;
using FlyingEye.DeviceClients;
using FlyingEye.Exceptions;
using FlyingEye.HttpServices;
using FlyingEye.SaveInfos;
using FlyingEye.SaveInfoServices;
using FlyingEye.Views;
using FlyingEye.Views.UserControls;
using Microsoft.Extensions.DependencyInjection;
using Microsoft.Extensions.Logging;
using System.Diagnostics;
using System.IO;
using System.Reflection;
using System.Windows;
using System.Windows.Input;

namespace FlyingEye.ViewModels
{
    public class MainWindowViewModel : ObservableObject
    {
        private readonly ComeNotificationService _comeNotificationService;

        private readonly ILogger<MainWindowViewModel> _logger;

        private readonly IServiceProvider _services;

        private string _userMessage;

        public string UserMessage
        {
            get { return _userMessage; }
            set { SetProperty(ref _userMessage, value); }
        }

        private Visibility _loadingVisibility;

        private readonly FlyingEyeClientApplication _application;

        public Visibility LoadingVisibility
        {
            get { return _loadingVisibility; }
            set
            {
                IsEnabled = LoadingVisibility == Visibility.Visible;
                SetProperty(ref _loadingVisibility, value);
            }
        }

        private bool _isEnabled;

        public bool IsEnabled
        {
            get { return _isEnabled; }
            set { SetProperty(ref _isEnabled, value); }
        }

        public string ResourceId { get; set; }

        public ICommand OpenCommand { get; set; }

        public ICommand CloseCommand { get; set; }

        private bool _isClosed;

        public bool IsClosed
        {
            get { return _isClosed; }
            set
            {
                SetProperty(ref _isClosed, value);
            }
        }

        private bool _isOpen;

        public bool IsOpen
        {
            get { return _isOpen; }
            set
            {
                SetProperty(ref _isOpen, value);
            }
        }

        private bool _isRuning;

        public bool IsRuning
        {
            get { return _isRuning; }
            set
            {
                _isRuning = value;
                IsClosed = !value;
                IsOpen = value;
            }
        }

        private DesktopNotificationUserControl _desktopNotification { get; set; }

        public MainWindowViewModel(
            FlyingEyeClientApplication application,
            ILogger<MainWindowViewModel> logger,
            DesktopNotificationUserControl desktopNotification,
            IServiceProvider services,
            ComeNotificationService comeNotificationService)
        {
            ResourceId = string.Empty;
            IsRuning = false;
            ResourceId = "TestDeviceClient";
            OpenCommand = new RelayCommand<Window>(OnOpen);
            CloseCommand = new RelayCommand<Window>(OnClose);
            LoadingVisibility = Visibility.Hidden;
            _application = application;
            _userMessage = string.Empty;
            _logger = logger;
            _desktopNotification = desktopNotification;
            _services = services;

            OnLoad();
            _comeNotificationService = comeNotificationService;
        }

        private void OnLoad()
        {
            try
            {
                var saveInfo = SaveInfo.Read<UserInputSaveInfo>();
                ResourceId = string.IsNullOrWhiteSpace(saveInfo.ResourceId) ? string.Empty : saveInfo.ResourceId;

                if (!string.IsNullOrWhiteSpace(ResourceId))
                {
                    this.OnOpen(null);
                }
            }
            catch (Exception ex)
            {
                HandyControl.Controls.MessageBox.Show("读取保存信息错误！", "错误提示", MessageBoxButton.OK, MessageBoxImage.Error);
                _logger.LogError(ex, ex.Message);
            }
        }

        private void Save()
        {
            try
            {
                var saveInfo = SaveInfo.Read<UserInputSaveInfo>();
                saveInfo.ResourceId = ResourceId;
                SaveInfo.Write(saveInfo);
            }
            catch (Exception ex)
            {
                HandyControl.Controls.MessageBox.Show("保存信息错误！", "错误提示", MessageBoxButton.OK, MessageBoxImage.Error);
                _logger.LogError(ex, ex.Message);
            }
        }

        private bool AuthCurrentUser(Window? window)
        {
            // 启动是自动登录
            if (window == null)
            {
                return true;
            }

            var authenticationWindow = _services.GetRequiredService<AuthenticationWindow>();
            authenticationWindow.Left = window.Left + 10;
            authenticationWindow.Top = window.Top + 10;
            var resutl = authenticationWindow.ShowDialog();
            return resutl == true;
        }

        private async void OnOpen(Window? window)
        {
            if (string.IsNullOrWhiteSpace(ResourceId))
            {
                HandyControl.Controls.MessageBox.Show(
                    "设备资源号不能为空！",
                    "输入提示",
                    MessageBoxButton.OK,
                    MessageBoxImage.Information);
                return;
            }

#if RELEASE
            if (!AuthCurrentUser(window))
            {
                return;
            }
#endif

            OpenLoading(); // 打开加载动画
            Save(); // 保存信息

            try
            {
                _application.DeviceManager.DeviceConnected -= OnDeviceConnected;
                _application.DeviceManager.DeviceConnected += OnDeviceConnected;

                var id = ResourceId.Trim();
                await _application.OpenAsync(id);
                await Task.Delay(1000);
                IsRuning = true;
            }
            catch (Exception ex)
            {
                if (ex is IUserFriendlyException)
                {
                    HandyControl.Controls.MessageBox.Show(ex.Message, "错误提示", MessageBoxButton.OK, MessageBoxImage.Error);
                }
                else
                {
                    HandyControl.Controls.MessageBox.Show("启用应用程序错误！", "错误提示", MessageBoxButton.OK, MessageBoxImage.Error);
                }

                _logger.LogError(ex, ex.Message);
            }
            finally
            {
                CloseLoading();
            }

        }

        private async void OnDeviceConnected(object? sender, DeviceConnectedEventArgs e)
        {
            await _comeNotificationService.PostMessage($"飞眼设备客户端 {this.ResourceId} 连接成功！");

            await System.Windows.Application.Current.Dispatcher.InvokeAsync(() =>
            {
                if (e.ConnectExceptions?.Any() == true)
                {
                    e.ConnectExceptions.ToList().ForEach(ex =>
                    {
                        _logger.LogError(ex, "设备连接错误");
                    });

                    _desktopNotification.Show("已更新飞眼设备客户端连接，但是部分设备连接错误！");
                }
                else
                {
                    _desktopNotification.Show("已更新飞眼设备客户端连接！");
                }
            });
        }

        private async void OnClose(Window? window)
        {
#if RELEASE
            if (AuthCurrentUser(window))
            {
                await CloseAsync();
            }
#else
            await CloseAsync();
#endif
            await _comeNotificationService.PostMessage($"飞眼设备客户端 {this.ResourceId} 断开连接！");
        }

        public async Task CloseAsync()
        {
            OpenLoading();
            await Task.Delay(1000);
            await _application.CloseAsync();
            IsRuning = false;
            CloseLoading();
        }

        private void OpenLoading()
        {
            LoadingVisibility = Visibility.Visible;
        }

        private void CloseLoading()
        {
            LoadingVisibility = Visibility.Hidden;
        }
    }
}
